//------------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from ARM Limited.
//
//            (C) COPYRIGHT 2008-2012 ARM Limited.
//                ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from ARM Limited.
//------------------------------------------------------------------------------
// Version and Release Control Information:
//
// File Revision       : 127275
// File Date           :  2012-03-19 15:37:15 +0000 (Mon, 19 Mar 2012)
// Release Information : PL401-r0p1-00eac0
//------------------------------------------------------------------------------
// Purpose             : This downsizer block takes incoming rbeat information 
//                       from the downsizer read channel and controls the  
//                       handshaking and assertion of correct rlast for
//                       merged read data beats presented to the wide bus.
//------------------------------------------------------------------------------


`include "nic400_ib_vgalcd_mst_axi4_ib_defs_ysyx_rv32.v"
`include "Axi.v"
//------------------------------------------------------------------------------
// Module Declaration
//------------------------------------------------------------------------------

module nic400_ib_vgalcd_mst_axi4_ib_downsize_rd_cntrl_ysyx_rv32
  (
    // Outputs
    rvalid_s,
    rlast_s,
    
    rready_m,
    
    // Inputs
    aclk, 
    aresetn,
    
    rready_s,
    
    rbeats,
    rvalid_m,
    rlast_m
    
  );


// ---------------------------------------------------------------------------
//  Port definitions
// ---------------------------------------------------------------------------

  input           aclk;
  input           aresetn;
  
  input [1:0]     rbeats;
  
  input           rready_s;
  input           rvalid_m;
  
  input           rlast_m;
    
  output          rvalid_s;
  output          rready_m;
  
  output          rlast_s;
 
//------------------------------------------------------------------------
// Wires  
//------------------------------------------------------------------------
          
  
  wire            rbeat_reg_wr_en;
  wire [1:0]      next_rbeat_reg;
  wire [1:0]      rbeat_in;  

  wire            busy_reg_wr_en;
  wire            busy_reg_next;
  wire            rready_m_i;
//------------------------------------------------------------------------
// Registered values
//------------------------------------------------------------------------
     
  reg  [1:0]      rbeat_reg;

  reg             busy_reg;


// ---------------------------------------------------------------------------
// Start of code
// ---------------------------------------------------------------------------

  // The read control block manages the handshake signals to allow the correct
  // number of rdata beats to be presented to the slave_if bus (wide side).
  // This accounts for any merging of subwidth beats into wide slots in 
  // the downsizer
  
  // Valids wired straight through
  assign rvalid_s = rvalid_m;
  
  // Enable for busy_reg
  assign busy_reg_wr_en = (rvalid_m & (rready_s || rready_m_i));
  
  // Decide when the rd_cntrl is busy and should be holding the rdata stable
  assign busy_reg_next = (rvalid_m & rready_m_i) ? 1'b0 : 
                         (((rvalid_m & rready_s) & (|rbeats)) ? 1'b1 : busy_reg);
  
  // Busy register
  always @(posedge aclk or negedge aresetn)
   begin : beat_reg_seq
     if (!aresetn) 
         busy_reg <= 1'b0;
     else if (busy_reg_wr_en)
         busy_reg <= busy_reg_next;
   end // rbeat_seq
                       
                         
  
  // Incoming rbeat information from the downsizer read channel
  assign rbeat_in = |rbeats ? (rbeats - {{1{1'b0}},1'b1}) : 
                                          {2{1'b0}};

  // Implementation of the count down of rbeats on every slave_if handshake
  // conditional also upon busy_reg
  assign next_rbeat_reg = ((busy_reg_next) & (~|rbeat_reg)) ? rbeat_in : 
                          (((busy_reg_next) & (rvalid_m & rready_s)) ? (rbeat_reg - {{1{1'b0}},1'b1}) : (rbeat_reg));

  // Enable for rbeat counter register below.
  assign rbeat_reg_wr_en =  (rvalid_m & rready_s);

  always @(posedge aclk or negedge aresetn)
   begin : rbeat_reg_seq
     if (!aresetn) 
         rbeat_reg <= 2'b0;
     else if (rbeat_reg_wr_en)
         rbeat_reg <= next_rbeat_reg;
   end // rbeat_seq
   
  // Generate ready signal to allow merged wide slot to be popped having
  // held for the correct number of beats onto slave_if 
  assign rready_m_i = rready_s & ((~|rbeats) || (busy_reg & (~|rbeat_reg)));
  assign rready_m   = rready_m_i;
  // Create rlast at the correct time
  assign rlast_s = rlast_m & ((~|rbeats) || (busy_reg & (~|rbeat_reg)));   


endmodule

`include "nic400_ib_vgalcd_mst_axi4_ib_undefs_ysyx_rv32.v"
`include "Axi_undefs.v"

